package com.flying.client.network;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.WriteCompletionEvent;

import com.flying.client.utils.Logger;

public class MsgEventHandler extends SimpleChannelUpstreamHandler{
	private static final Logger logger = Logger.getLogger(MsgEventHandler.class.getName());
	
	private NetworkProvider networkProvider = null;
	
	public MsgEventHandler(NetworkProvider networkProvider)
	{
		this.networkProvider = networkProvider;
	}
	
	@Override
    public void exceptionCaught(
            ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
        
		logger.debug("exceptionCaught "+ e.getCause() +" ctx=" + ctx + " attachment="+e.getChannel().getAttachment());
    	super.exceptionCaught(ctx, e);
    	
    	NetworkAttachment attachment = (NetworkAttachment)e.getChannel().getAttachment();
    	NetworkClient client = null;
    	if (attachment != null)
    	{
    		client = attachment.client;
    	}
        this.networkProvider.onError(e.getCause(),client);
        
        ctx.getChannel().close();
    }

    @Override
    public void channelOpen(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        logger.debug("channelOpen");
    	super.channelOpen(ctx, e);
        
    }

    /**
     * Invoked when a {@link Channel} is open, bound to a local address, and
     * connected to a remote address.
     * <br/>
     *
     * <strong>Be aware that this event is fired from within the Boss-Thread so you should not
     * execute any heavy operation in there as it will block the dispatching to other workers!</strong>
     */
    @Override
    public void channelConnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        logger.debug("channelConnected ctx="+ctx.getChannel().isConnected() + " "+e.getState().name() + " "+e.getValue());
    	super.channelConnected(ctx, e);
    	
    	//NetworkClient client = (NetworkClient)ctx.getAttachment();
        //NetworkProvider.getInstance().onConnected(NetworkResult.STATUS_SUCCESSED,client);
    }

    /**
     * Invoked when a {@link Channel}'s {@link Channel#getInterestOps() interestOps}
     * was changed.
     */
    @Override
    public void channelInterestChanged(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    	logger.debug("channelInterastChanned");
        super.channelInterestChanged(ctx, e);
    }

    /**
     * Invoked when a {@link Channel} was disconnected from its remote peer.
     */
    @Override
    public void channelDisconnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        logger.debug("channelDisconnectd");
        super.channelDisconnected(ctx, e);
        NetworkClient client = (NetworkClient)ctx.getAttachment();
        this.networkProvider.onDisconnection(client);
    }

    /**
     * Invoked when a {@link Channel} was closed and all its related resources
     * were released.
     */
    public void channelClosed(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
       logger.debug("channelClosed");
       super.channelClosed(ctx, e);
       
       NetworkClient client = (NetworkClient)ctx.getAttachment();
       this.networkProvider.onClosed(client);
    }

    /**
     * Invoked when something was written into a {@link Channel}.
     */
    public void writeComplete(
            ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
    	
        logger.debug("writeComplete e="+e);
        super.writeComplete(ctx, e);
    }
}
